Files
calctext/_bmad-output/C-UX-Scenarios/02-calculation-experience/2.1-editor/2.1-editor.md
C. Cassel 0d38bd3108 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>
2026-03-18 09:12:05 -04:00

11 KiB
Raw Blame History

2.1 — Editor

Next Step:Results Panel


Page Metadata

Property Value
Scenario 02 — Calculation Experience
Page Number 2.1
Platform Web (PWA), portable to macOS/Windows
Page Type Embedded Panel (within App Shell main area)
Viewport All breakpoints
Interaction Keyboard-primary, mouse secondary

Overview

Page Purpose: The editor is where calculations happen. Users type natural-language math expressions, define variables, add comments, and organize their thinking. It must feel like a fast, responsive text editor — not a calculator widget.

User Situation: User is actively thinking through numbers. They're writing a budget, converting units, figuring out a mortgage, or doing quick math. The editor must never get in their way — every keystroke should feel instant.

Success Criteria:

  • Typing latency < 16ms (60fps)
  • Results update within 50ms of pause (debounce)
  • Syntax highlighting aids comprehension without distraction
  • Errors are visible but non-intrusive
  • Visual hierarchy makes 50-line documents scannable

Entry Points:

  • Opening a document (tab click, sidebar double-click, new document)
  • Returning to active document

Exit Points:

  • Switching tabs (editor content swaps)
  • Closing document

Reference Materials

Existing Implementation:

  • calcpad-web/src/editor/CalcEditor.tsx — Current CodeMirror wrapper
  • calcpad-web/src/editor/calcpad-language.ts — Syntax highlighting
  • calcpad-web/src/editor/error-display.ts — Error underlines + gutter
  • calcpad-web/src/editor/inline-results.ts — Zebra striping

Design System:


Layout Structure

┌──────────────────────────────────────────┐
│ [Gutter] [Line Content]                  │
│                                          │
│  1  │ # Monthly Budget                   │  ← heading (bold, larger)
│  2  │                                    │  ← empty line
│  3  │ // Income                          │  ← comment (muted)
│  4  │ salary = 5000                      │  ← variable assignment
│  5  │ freelance = 1200                   │  ← variable assignment
│  6  │ total_income = salary + freelance  │  ← expression
│  7  │                                    │
│  8  │ // Expenses                        │  ← comment
│  9  │ rent = 1500                        │
│ 10  │ groceries = 400                    │
│ 11  │ utilities = rent * 5%  ̰ ̰ ̰ ̰        │  ← error underline
│ 12  │                                    │
│ 13  │ total_expenses = sum              │  ← aggregator
│ 14  │ savings = total_income - total_exp │
│     │                                    │
│     │                                    │
└──────────────────────────────────────────┘
  Zebra striping on alternating lines

Spacing

Property Token Pixels
Content padding top/bottom space-sm 8px
Line padding horizontal space-md 12px
Gutter width 40px (auto-expands for > 999 lines)
Gutter padding right space-xs 6px
Line height 24px (15px font × 1.6)
Error gutter width 20px

Change from current: Reduced line padding from 16px → 12px to match macOS's tighter feel.


Typography

Element Size Weight Typeface Color
Line content text-md (15px) 400 system mono var(--text)
Headings (# lines) text-md (15px) 700 system mono var(--text-h)
Comments (// lines) text-md (15px) 400 italic system mono var(--text) at 50% opacity
Variable names text-md (15px) 400 system mono var(--syntax-variable)
Numbers text-md (15px) 400 system mono var(--syntax-number)
Operators text-md (15px) 400 system mono var(--syntax-operator)
Keywords text-md (15px) 500 system mono var(--syntax-keyword)
Functions text-md (15px) 400 system mono var(--syntax-function)
Currency symbols text-md (15px) 400 system mono var(--syntax-currency)
Line numbers (gutter) text-xs (13px) 400 system mono var(--text) at 40% opacity
Active line number text-xs (13px) 600 system mono var(--text)

Syntax Highlighting Tokens

New CSS custom properties for syntax colors, per-theme:

Token Light Dark Matrix
--syntax-variable #4f46e5 (indigo-600) #a5b4fc (indigo-300) #00ff41
--syntax-number #0d9488 (teal-600) #5eead4 (teal-300) #00cc33
--syntax-operator #6b6375 (text) #9ca3af (text) #00ff41
--syntax-keyword #7c3aed (violet-600) #c4b5fd (violet-300) #39ff14
--syntax-function #2563eb (blue-600) #93c5fd (blue-300) #00ff41
--syntax-currency #d97706 (amber-600) #fcd34d (amber-300) #ffff00
--syntax-comment rgba(text, 0.5) rgba(text, 0.5) rgba(#00ff41, 0.4)
--syntax-heading var(--text-h) var(--text-h) #00ff41
--syntax-error #e53e3e #fc8181 #ff0000

Visual Hierarchy Improvements

Headings (# lines)

Property Value
Font weight 700 (bold)
Color var(--text-h) — strongest text color
Top margin 8px extra (visual section break) — only if preceded by non-empty line
Bottom margin 0 (heading belongs to content below)
Background None (clean)

Comments (// lines)

Property Value
Font style Italic
Opacity 50% of text color
No background stripe Comments skip zebra striping (visually distinct already)

Empty Lines

Property Value
Height 24px (same as content lines)
Background Normal zebra stripe pattern
Purpose Visual breathing room, section separators

Active Line

Property Value
Background var(--accent-bg) — subtle accent tint
Gutter Line number bold + full opacity
Transition background 0.1s

Error Display

Error Underline

OBJECT ID: editor-error-underline

Property Value
Style wavy underline
Color var(--syntax-error)
Thickness 1.5px
Scope Underlines the specific token/expression that errored

Error Gutter Marker

OBJECT ID: editor-error-gutter

Property Value
Icon ⚠ (warning triangle)
Size 14px
Color var(--syntax-error)
Position Error gutter column (20px wide, left of line numbers)
Hover Tooltip with error message text

Error Tooltip

OBJECT ID: editor-error-tooltip

Property Value
Trigger Hover over error gutter marker OR underlined text
Background var(--bg-secondary)
Border 1px solid var(--border)
Border-radius 4px
Padding 4px 8px
Font text-xs, system sans, var(--syntax-error)
Shadow 0 2px 8px rgba(0,0,0,0.15)
Max width 300px
Position Below the error line, left-aligned with gutter

Zebra Striping

Property Value
Pattern Even-numbered lines (matching current implementation)
Light mode rgba(0, 0, 0, 0.02) — reduced from 0.025
Dark mode rgba(255, 255, 255, 0.025) — reduced from 0.035
Matrix mode rgba(0, 255, 65, 0.03) — green tint
Skip on Comment lines (already visually distinct)

Autocomplete

OBJECT ID: editor-autocomplete

Property Value
Trigger Typing 2+ characters that match a variable, function, or keyword
Panel Dropdown below cursor, var(--bg) bg, 1px border, 4px radius
Max items 8 visible, scroll for more
Item height 28px
Active item var(--accent-bg) highlight
Categories Variables (with last value), Functions (with signature), Keywords, Units, Currencies
Keyboard ↑↓ to navigate, Tab/Enter to accept, Esc to dismiss
Auto-dismiss On cursor movement away

Page States

State When Behavior
Active editing User is typing Debounced eval (50ms). Results update. Auto-save (500ms).
Idle User paused All results current. Document saved.
Read-only Template preview (future) No cursor, no editing. Gray overlay on gutter.
Engine loading WASM initializing Editor is fully editable. Results show "—" until engine ready.
Large document > 500 lines Viewport rendering only (CodeMirror handles this). Performance warning in status bar if > 1000 lines.

Interactions

Action Behavior
Type expression Debounced eval → results update in 50ms
Define variable (x = 5) Variable registered, available for autocomplete on subsequent lines
Reference variable Autocomplete suggests matching variables with their current values
Use aggregator (sum, total) Aggregates all numeric results above (up to previous heading or empty line block)
Line reference (#3) References result of line 3
Comment (// text) Line excluded from evaluation, styled as comment
Heading (# text) Section header, not evaluated, used for visual grouping and aggregator scoping
Select text Selection count shown in status bar
Cmd/Ctrl+Z Undo (per-document history preserved while tab is open)
Cmd/Ctrl+Shift+Z Redo
Cmd/Ctrl+D Duplicate current line
Cmd/Ctrl+/ Toggle comment on current line
Alt+↑/↓ Move line up/down

Technical Notes

  • CodeMirror instance management: One instance per active tab. Inactive tabs store EditorState (preserves undo history). On tab switch, create new EditorView with stored state.
  • Eval debounce: 50ms (current). Consider making configurable in settings (0200ms range).
  • Syntax highlighting performance: StreamLanguage parser runs synchronously — fine for < 1000 lines. For very large documents, consider switching to Lezer grammar.
  • Font scaling: Expose font size setting (1224px range) in settings. Current 15px is good default. Store in localStorage.
  • Cross-platform: CodeMirror handles keyboard differences (Cmd vs Ctrl). Same extension stack works everywhere via WASM.

Open Questions

# Question Context Status
1 Should headings have extra top margin? Creates visual sections but breaks 1:1 line alignment with results panel 🟡 In Discussion — likely yes, results panel adjusts
2 Should comments skip zebra striping? Makes them more visually distinct but breaks the pattern 🔴 Open
3 Font size as user preference? 1224px range slider in settings 🟢 Resolved: Yes, default 15px

Next Step:Results Panel


Created using Whiteport Design Studio (WDS) methodology