2.2 — Results Panel
Previous Step: ← Editor
Page Metadata
| Property |
Value |
| Scenario |
02 — Calculation Experience |
| Page Number |
2.2 |
| Platform |
Web (PWA), portable to macOS/Windows |
| Page Type |
Embedded Panel (within App Shell main area) |
| Viewport |
Desktop + tablet (side panel), mobile (bottom tray) |
Overview
Page Purpose: Display calculation results aligned line-by-line with the editor. Results are the reason the product exists — they must be clear, informative, and subtly styled so they complement the editor without competing for attention.
User Situation: User is typing in the editor and their eyes flick right to see results. This happens dozens of times per session. The results must be instantly scannable — the eye should find the answer in milliseconds.
Success Criteria:
- Every result line aligns pixel-perfectly with its editor line
- Results are readable but visually secondary to the editor
- Different result types are distinguishable at a glance
- Scroll synchronization is seamless
Entry Points:
- Always visible on desktop/tablet (side panel)
- Toggle on mobile (bottom tray)
Layout Structure
Desktop/Tablet (side panel)
Mobile (bottom tray)
Spacing
| Property |
Token |
Pixels |
| Content padding top/bottom |
space-sm |
8px (matches editor) |
| Result line padding horizontal |
space-md |
12px (matches editor) |
| Result line height |
— |
24px (matches editor exactly) |
| Mobile tray collapsed height |
— |
48px |
| Mobile tray expanded height |
— |
40vh |
| Mobile drag handle |
— |
32px × 4px pill |
Typography
| Element |
Size |
Weight |
Typeface |
Color |
| Numeric result |
text-md (15px) |
400 |
system mono |
var(--result-number) |
| Unit value |
text-md (15px) |
400 |
system mono |
var(--result-unit) |
| Currency value |
text-md (15px) |
400 |
system mono |
var(--result-currency) |
| DateTime result |
text-md (15px) |
400 |
system mono |
var(--result-datetime) |
| Boolean result |
text-md (15px) |
400 |
system mono |
var(--result-boolean) |
| Error hint |
text-xs (13px) |
400 |
system sans |
var(--text) at 30% opacity |
| Non-result lines |
— |
— |
— |
Empty (no text rendered) |
Design change from current: Weight reduced from 600 → 400. Color changed from var(--accent) to type-specific semantic colors. This makes results secondary to the editor content, matching macOS behavior.
Result Type Colors
New CSS custom properties per theme:
| Token |
Light |
Dark |
Matrix |
Purpose |
| --result-number |
#374151 (gray-700) |
#d1d5db (gray-300) |
#00ff41 |
Plain numbers |
| --result-unit |
#0d9488 (teal-600) |
#5eead4 (teal-300) |
#00cc33 |
Values with units (5 kg, 3.2 m) |
| --result-currency |
#d97706 (amber-600) |
#fcd34d (amber-300) |
#ffff00 |
Currency values ($50, €42) |
| --result-datetime |
#7c3aed (violet-600) |
#c4b5fd (violet-300) |
#39ff14 |
Dates and times |
| --result-boolean |
#6366f1 (indigo-500) |
#818cf8 (indigo-400) |
#00ff41 |
true/false |
| --result-error |
var(--text) at 30% |
var(--text) at 30% |
rgba(#ff0000, 0.3) |
Error hint text |
Why type-specific colors: Users scanning results can instantly distinguish "that's a currency" from "that's a unit" from "that's a date" without reading the value. The colors are muted (not saturated) so they don't compete with the editor.
Result Display Format
| Result Type |
Display Format |
Example |
| Number |
Formatted with thousand separators |
6,200 |
| Unit value |
Value + unit abbreviation |
2.2 kg · 156.2 mi |
| Currency |
Symbol + value |
$4,300 · €3,857.20 |
| DateTime |
Locale-formatted |
Mar 25, 2026 · 14:30 |
| TimeDelta |
Human-readable |
3 days, 4 hours |
| Boolean |
Lowercase |
true · false |
| Comment |
Empty line (dash marker) |
──── (subtle horizontal line) |
| Heading |
Empty line (dash marker) |
──── |
| Empty |
Empty line |
(blank) |
| Error |
Muted hint |
· error (tiny, de-emphasized) |
| Variable assignment |
Show assigned value |
5,000 |
Change from current: Removed the = prefix before results. Just show the value. Cleaner.
| Property |
Value |
| Content |
──── (4 em dashes, or CSS border-bottom) |
| Color |
var(--border) at 50% opacity |
| Purpose |
Visual separator showing this line has no numeric result |
| Width |
60% of panel width, right-aligned |
Error Hint
| Property |
Value |
| Content |
· error or · invalid |
| Color |
var(--text) at 30% opacity |
| Purpose |
Subtle indicator that something went wrong — details are in the editor gutter |
| Font |
text-xs (13px), system sans |
Zebra Striping
| Property |
Value |
| Pattern |
Matches editor exactly (same even-line pattern) |
| Colors |
Same as editor per theme |
| Sync |
Uses line index, not DOM position, for consistency |
Scroll Synchronization
| Property |
Value |
| Direction |
Editor drives, results follows |
| Method |
scrollTop mirroring via passive scroll listener |
| Latency |
< 1 frame (requestAnimationFrame if needed) |
| Results panel |
overflow-y: hidden — no independent scrolling |
| Edge case |
If editor has heading margins (extra space), results panel inserts matching spacers |
Result Hover Interaction
OBJECT ID: results-hover
| Property |
Value |
| Trigger |
Mouse hover over a result line |
| Behavior |
Show full precision + unit details in tooltip |
| Tooltip content |
Raw value (full precision), type label, conversion hint |
| Example |
Hover $4,300 → "4300.00 USD (United States Dollar)" |
| Example |
Hover 2.2 kg → "2.20462 kg (kilogram) · 4.85 lb" |
| Style |
Same as error tooltip (bg-secondary, border, 4px radius) |
| Delay |
500ms hover delay (don't trigger on casual mouse movement) |
Result Click Interaction
OBJECT ID: results-click
| Property |
Value |
| Trigger |
Single click on a result value |
| Behavior |
Copy raw value to clipboard |
| Feedback |
Brief flash (0.3s) — result text turns var(--success) then fades back |
| Tooltip |
"Copied!" appears for 1.5s |
| Accessibility |
aria-label="Copy result: {value}" |
Mobile Bottom Tray
OBJECT ID: results-mobile-tray
Collapsed State (48px)
| Property |
Value |
| Content |
Drag handle + last non-empty result value |
| Drag handle |
32px × 4px pill, var(--border), centered |
| Result text |
"Last: {value}" or "No results" if empty |
| Font |
text-xs, var(--text) |
| Background |
var(--bg-secondary) |
| Border |
top 1px solid var(--border) |
| Interaction |
Tap or swipe up → expand |
Expanded State (40vh)
| Property |
Value |
| Content |
Scrollable list of all line results paired with their expressions |
| Item format |
Ln {n}: {expression} → {result} |
| Item height |
36px (larger for touch) |
| Active line |
Highlighted with var(--accent-bg) |
| Tap result |
Copy to clipboard (same as desktop click) |
| Interaction |
Swipe down → collapse. Tap backdrop → collapse. |
| Scroll |
Independent scroll (not synced with editor in mobile) |
Transitions
| Property |
Value |
| Expand/collapse |
200ms ease-out |
| Spring |
Optional subtle overshoot on expand |
Page States
| State |
When |
Results Display |
| Normal |
Engine ready, results computed |
Type-colored values per line |
| Engine loading |
WASM initializing |
All result lines show — in var(--text) at 20% |
| Empty document |
No lines in editor |
Panel is blank |
| All errors |
Every line has errors |
All lines show muted · error hints |
| Stale results |
Document changed, eval pending |
Previous results stay visible (no flash/flicker) |
Accessibility
| Feature |
Implementation |
| ARIA |
role="complementary", aria-label="Calculation results" |
| Live updates |
aria-live="polite" on result container — announces new results |
| Screen reader |
Each result: aria-label="Line {n}: {expression} equals {result}" |
| Color-blind |
Result types distinguishable by position + format, not just color |
| Click feedback |
aria-label="Copied" announced on clipboard copy |
| Reduced motion |
No flash animation; instant color change for copy feedback |
Technical Notes
- Result alignment: Line height must match editor exactly (24px). If editor adds heading margins, results panel must add matching spacer divs.
- Rendering: ResultsPanel receives
EngineLineResult[] from useEngine hook. Re-renders only changed lines (React key by line index).
- Copy to clipboard: Use
navigator.clipboard.writeText(). Fall back to textarea trick for older browsers.
- Hover tooltip positioning: Position below the result line, right-aligned with panel. Flip above if near viewport bottom.
- Mobile tray: Use CSS
transform: translateY() for smooth expand/collapse. Touch events for swipe gesture.
- Cross-platform: Side panel → native split view (macOS/Windows). Mobile tray → not applicable on desktop native.
Open Questions
| # |
Question |
Context |
Status |
| 1 |
Should heading lines in results show ──── markers? |
Helps visual alignment but adds visual noise |
🔴 Open |
| 2 |
Should copy-on-click copy formatted or raw value? |
$4,300 vs 4300 |
🟡 — Likely raw (more useful for pasting) |
| 3 |
Result hover tooltip — show conversion alternatives? |
"2.2 kg · 4.85 lb" on hover |
🟢 Resolved: Yes, useful for unit/currency results |
Previous Step: ← Editor
Created using Whiteport Design Studio (WDS) methodology