This file is the authoritative visual and interaction contract for the standalone NeuronLab frontend prototype. The approved specification and corrected implementation plan define product behavior. This contract defines how that behavior is composed, themed, made responsive, and made accessible. When reference fidelity conflicts with task completion or accessibility, task completion and accessibility win.
- Product brief:
docs/superpowers/specs/2026-08-11-neuronlab-fresh-frontend-design.md. - Corrected implementation plan:
.omo/plans/2026-08-11-neuronlab-fresh-frontend.md. - Embedded reference findings:
.omo/start-work/artifacts/task-0/embedded-reference-report.md. - Real-product screen findings:
.omo/start-work/artifacts/task-0/lazyweb/report.md. - Concept comparison:
.omo/start-work/artifacts/task-0/concepts/report.md.
- Shortlist: IBM, Notion, and Figma.
- Selection:
taste-skillfor execution discipline plus IBM as a structural Layer B reference. - Take from IBM: precise technical hierarchy, IBM Plex Sans and Mono typography, measured density, an 8px working rhythm, and a 16-column alignment frame. Its former rectilinear-only anatomy and tonal-depth-only treatment are superseded for ordinary controls and shared surfaces by the user-selected HeroUI live reference.
- Leave from IBM: every color value, Carbon token name, Carbon component API, logo, icon, brand treatment, and proprietary detail.
- Notion contributes only the comparison standard of restrained reading measure. Its serif-led warm identity is not adopted.
- Figma contributes only the principle that tools stay subordinate to the learner's task. Its multicolor identity and infinite-canvas behavior are not adopted.
- Three desktop queries were run:
machine learning education dashboard,interactive mathematics lesson, andcoding problem workspace. - Six screens were viewed: Circle course dashboard, Uxcel learning dashboard, CK-12 Math Analysis lesson detail, Mathway Precalculus workspace, Replit tutorial workspace, and Udemy coding exercise.
- Extracted grammar: a stable shell with task-specific centers; an activity-first dashboard; constrained lesson reading measure; scope-based navigation; persistent local progression; bounded problem panes; visible progress, selected, empty, loading, error, and execution states; and narrow-screen reflow that collapses rails before compressing primary learning content.
- The research images remain unshipped references under
.omo/start-work/artifacts/task-0/lazyweb/. No product copy, brand asset, or pixel layout is copied from them.
- Drafts inspected:
.omo/start-work/artifacts/task-0/concepts/notebook-laboratory.png,.omo/start-work/artifacts/task-0/concepts/graph-paper-studio.png, and.omo/start-work/artifacts/task-0/concepts/focused-split-workbench.png. - Selected reference-fidelity concept:
.omo/start-work/artifacts/task-0/concepts/graph-paper-studio.png. - Selection reason: it gives the mathematical canvas the strongest visual priority, makes direct manipulation part of the learning argument, establishes a clear context-to-reflection sequence, and communicates the most credible responsive intent/model. The static image is not evidence that any reflow behavior works.
- Carry forward: slim masthead, full-width mastery roadmap, instructional strip, dominant graph-paper canvas, docked apparatus region, and persistent progression action. Preserve the learning order when these regions reflow.
- Supporting references:
focused-split-workbench.pnginforms only/problem/[id];notebook-laboratory.pnginforms only long-form derivation anatomy. - Exclude generated mathematical copy, generated navigation labels, implementation annotations, exact icons, and any unreviewed graph or formula content, including the plotted point near
w ≈ 3.2while its coordinate, tangent, and readout statew = 2.000, plus the ambiguous\hat{w}_inotation underL(w). These are defects in generated reference imagery and must not be reused as factual lesson content without subject-matter review. - Skipped lanes: none.
The synthesis used the frontend design router, design-system architecture, taste-skill, IBM structural reference, layout mechanics, interaction mechanics, image-to-code reference-fidelity rules, OpenChamber semantic-token rules, and designpowers Lane A through Lane D guidance. For Task 7, the user-selected live HeroUI theme reference at https://heroui.com/en/themes?hue=349.13712993236084&base=0.02 remains authoritative for component anatomy, a base radius of 0.5rem, medium radius of 0.375rem, field radius of 0.75rem, and 36px visual desktop controls. The user explicitly selects a flat-modern interpretation rather than the reference's macOS-like dimensional depth: ordinary controls and surfaces use tonal relationships, thin borders, and spacing with no shadow; only genuine overlays retain the stronger overlay shadow. The URL hue and base are provenance and visual direction only; OpenChamber remains the runtime color source for every variant. The design dials remain DESIGN_VARIANCE 5, MOTION_INTENSITY 3, and VISUAL_DENSITY 6.
NeuronLab feels like a light-first scientific learning studio: part engineered textbook, part instrumented laboratory. The atmosphere is precise, calm, clean, and lightly playful without becoming institutional or terminal-like. Its signature is the graph-paper learning plane, where derivation, direct manipulation, live mathematical evidence, reflection, and one next action share a visible sequence. HeroUI's medium-radius component anatomy governs ordinary controls and shared surfaces, while flat semantic zoning, thin borders, and spacing carry hierarchy; the scientific content structure and graph-paper signature remain NeuronLab-specific.
| Dial | Value | Contract |
|---|---|---|
DESIGN_VARIANCE |
5/10 | Use measured asymmetry and offset instructional composition while keeping diagnostic, lesson, remediation, and mastery wayfinding predictable. |
MOTION_INTENSITY |
3/10 | Use short feedback and orientation transitions only. No decorative choreography, perpetual motion, or scroll hijacking. |
VISUAL_DENSITY |
6/10 | Keep technical context visible in roadmaps, activity, lessons, editors, and results, while preserving a readable prose measure and progressive disclosure. |
- Current position is always visible. Learners can identify where they are, what is complete, what is blocked, and what to do next without recalling a previous screen.
- Mathematics leads implementation. Concept, derivation, visualization, example, and conceptual check precede the practical mastery gate.
- Evidence beats decoration. Graphs, equations, execution results, lock reasons, and activity are product content. Decorative KPI cards, glows, and generic bento modules are not.
- One primary action per context. Primary color means act. Selection means current. Status means actual feedback.
- Mistakes preserve work. Partial reasoning, valid execution output, completed lesson stages, and local state survive retry whenever the approved mock contract permits it.
- Prototype behavior is honest. Fixtures, simulated streams, mock accounts, and local persistence are labeled. No production claim, fabricated metric, testimonial, rank, or engagement statistic appears.
- Wide lesson stages use a slim product masthead, a visible mastery roadmap, an instructional region, a dominant mathematical canvas, an apparatus region, and a reachable progression action.
- Visual and DOM order is always: context, explanation or derivation, manipulation, reflection or check, then progression.
- The graph-paper field is localized to genuine mathematical work. It is not a site-wide decorative wallpaper.
- The global product must not copy the generated concept's exact navigation taxonomy, lesson copy, control labels, icons, or mathematics.
- The problem route uses a focused split workbench, not the graph-paper composition forced onto an editor task.
Do not build a terminal imitation, generic SaaS dashboard, three-equal-card feature row, decorative status-dot system, purple AI gradient, glass surface stack, pill-heavy interface, or shadowed container around every content group. Do not expose responsive implementation notes in learner-facing copy.
OpenChamber is the only source of application color values. Every one of the 42 pinned OpenChamber variants resolves into the same NeuronLab semantic shape. Feature components, HeroUI adaptations, Monaco, math, diagrams, charts, graph paper, overlays, and status surfaces consume only --nl-* semantic variables. No raw preset value, Tailwind palette color, IBM value, Carbon token, copied neutral ramp, or one-theme global palette may appear in feature styling.
The 42 variants are grouped into exactly these 21 selectable families: openchamber, flexoki, fields-of-the-shire, aura, ayu, carbonfox, catppuccin, dracula, gruvbox, jetbrains, kanagawa, monokai, nightowl, nord, onedarkpro, solarized, tokyonight, vesper, mono-plus, mono, and vitesse. Source metadata IDs remain unchanged, including vitesse-dark-dark and vitesse-light-light.
For every variant, the resolver maps the corresponding OpenChamber source semantic directly into these NeuronLab roles. A theme is publishable only when every relationship exists and passes its required contrast use.
| NeuronLab role | CSS variable | Relationship and use |
|---|---|---|
surface.background |
--nl-surface-background |
Direct source surface background. Root page and shell canvas. |
surface.elevated |
--nl-surface-elevated |
Direct source elevated surface. Fields, panels, cards, and floating content base. |
surface.muted |
--nl-surface-muted |
Direct source muted surface. Secondary zones and subdued bands; shared application shell chrome stays on surface.background. |
surface.foreground |
--nl-surface-foreground |
Direct source foreground. Primary text, axes, and high-priority labels. |
surface.subtle |
--nl-surface-subtle |
Direct source subtle role. Secondary text and low-emphasis separators where the source semantics support that use. |
interactive.border |
--nl-interactive-border |
Direct source border. Hairlines, field edges, and graph structure. |
interactive.hover |
--nl-interactive-hover |
Direct source hover. Interactive elements only. |
interactive.active |
--nl-interactive-active |
Direct source active. Pressed interaction state only. |
interactive.selection |
--nl-interactive-selection |
Direct source selection. Current navigation, tab, roadmap item, stage, or theme choice. |
interactive.selectionForeground |
--nl-interactive-selection-foreground |
Direct source selection foreground. Content placed on selection. |
interactive.focusRing |
--nl-interactive-focus-ring |
Direct source focus or focus-ring semantic after accessibility validation. |
primary.base |
--nl-primary-base |
Direct source primary base. The one primary local action. |
primary.hover |
--nl-primary-hover |
Direct source primary hover. Primary-action hover only. |
primary.active |
--nl-primary-active |
Direct source primary active. Pressed primary-action fill only. |
primary.foreground |
--nl-primary-foreground |
Direct source primary foreground. Content on primary action. |
status.error.* |
--nl-status-error-{base,foreground,background,border} |
Direct error family. Validation and failed operations only. |
status.warning.* |
--nl-status-warning-{base,foreground,background,border} |
Direct warning family. Cautions and persistence warnings only. |
status.success.* |
--nl-status-success-{base,foreground,background,border} |
Direct success family. Confirmed completion and mastery only. |
status.info.* |
--nl-status-info-{base,foreground,background,border} |
Direct information family. Neutral system information only. |
syntax.background |
--nl-syntax-background |
Direct colors.syntax.base.background. Monaco and code surfaces only. |
syntax.foreground |
--nl-syntax-foreground |
Direct colors.syntax.base.foreground. Default code text only. |
syntax.comment |
--nl-syntax-comment |
Direct colors.syntax.base.comment. |
syntax.keyword |
--nl-syntax-keyword |
Direct colors.syntax.base.keyword. |
syntax.string |
--nl-syntax-string |
Direct colors.syntax.base.string. |
syntax.number |
--nl-syntax-number |
Direct colors.syntax.base.number. |
syntax.function |
--nl-syntax-function |
Direct colors.syntax.base.function. |
syntax.variable |
--nl-syntax-variable |
Direct colors.syntax.base.variable. |
syntax.type |
--nl-syntax-type |
Direct colors.syntax.base.type. |
syntax.operator |
--nl-syntax-operator |
Direct colors.syntax.base.operator. |
Visualization roles are derived only from existing source semantics. They never introduce an independent palette.
| Visualization role | CSS variable | Required derivation |
|---|---|---|
visualization.series[0] |
--nl-visualization-series-1 |
primary.base |
visualization.series[1] |
--nl-visualization-series-2 |
status.info.base |
visualization.series[2] |
--nl-visualization-series-3 |
status.success.base |
visualization.series[3] |
--nl-visualization-series-4 |
status.warning.base |
visualization.series[4] |
--nl-visualization-series-5 |
status.error.base |
visualization.graphEdge |
--nl-visualization-graph-edge |
interactive.border |
visualization.mathEmphasis |
--nl-visualization-math-emphasis |
primary.base |
visualization.diagramContrast |
--nl-visualization-diagram-contrast |
surface.foreground |
Graph-paper minor lines use surface.subtle; major lines and axes use interactive.border and surface.foreground; the primary curve and manipulable point use visualization.series[0]; tangent and guide geometry use visualization.graphEdge; formula emphasis uses visualization.mathEmphasis. Meaning is also provided by line style, shape, label, or text.
- Transparent, malformed, or contrast-invisible focus values fail the resolver boundary.
- The smallest source-ID-specific override is permitted only to repair invalid accessibility semantics. For
vitesse-dark-darkandvitesse-light-light, the invalid transparent focus value resolves to that same variant'sprimary.base. This is an accessibility correction, not a new global palette. - Required minimum contrast is 4.5:1 for body text, 3:1 for large text and UI boundaries, and 3:1 for the visible focus indicator against adjacent colors.
- Status, mastery, selection, and lock states always include text and an icon, shape, or line treatment. Color is never the sole signal.
- A variant that fails text, focus, status, math, diagram, editor, or overlay contrast is not published until its mapping is corrected.
primary.*means act;interactive.selection*means current;status.*means feedback;syntax.*means code;visualization.*means mathematical or diagrammatic content. These roles do not substitute for one another.
- Interface, reading, and display family: IBM Plex Sans, self-hosted or loaded through the approved Next.js font path.
- Code, coordinates, test output, deterministic metadata, and compact technical labels: IBM Plex Mono.
- Mathematical notation: KaTeX's purpose-built math fonts inside rendered equations only. They are content notation, not a third brand typeface.
- Product copy calls these roles
SansandMono. No IBM logo, name treatment, icon font, Carbon branding, or IBM brand claim appears in the interface. - Use only weights 300, 400, and 600. Weight 700 is not part of this system.
Implementation uses rem; pixel equivalents below document the reviewed optical target at the default browser size.
| Token | Size / line height | Weight | Tracking | Use |
|---|---|---|---|---|
type.display |
3.75rem / 4.375rem (60/70) |
300 | normal | Landing display only; responsive clamp() must keep it within three lines. |
type.page |
2.625rem / 3.125rem (42/50) |
300 | normal | Page identity and major lesson title. |
type.section |
2rem / 2.5rem (32/40) |
400 | normal | Major section heading. |
type.subsection |
1.5rem / 2rem (24/32) |
400 | normal | Stage, grouped content, or panel heading. |
type.component |
1.25rem / 1.75rem (20/28) |
600 | normal | Component or card heading. |
type.body |
1rem / 1.5rem (16/24) |
400 | normal | Default reading, lesson, remediation, and form text. |
type.bodyStrong |
1rem / 1.5rem (16/24) |
600 | normal | Emphasis and important labels. |
type.compact |
0.875rem / 1.25rem (14/20) |
400 or 600 | 0.01rem |
Navigation, compact UI, code, and output. |
type.metadata |
0.75rem / 1rem (12/16) |
400 or 600 | 0.02rem |
Timestamps, metadata, helper text, and compact status labels. |
- Long lesson and remediation prose stays near 65ch and within the inclusive 45-75 character range.
- Headings use balanced wrapping; body text uses readable ragged-right wrapping. No justified prose.
- Body text never drops below
1rem. Compact and metadata sizes are reserved for supporting UI, not instructions required to complete a task. - Dynamic counts and timings use tabular numerals. Code and coordinates use Mono, not body Sans styled to resemble code.
- Display tracking remains neutral. Small-size micro-tracking applies only to the two documented compact levels.
- Equations scroll horizontally inside their own math surface when necessary. They never widen the document or app shell.
- Line height, paragraph spacing, and layout must tolerate WCAG text-spacing overrides and 200% zoom without clipping.
All spacing intent derives from a 4px base. The normal composition rhythm is 8px, with 4px reserved for close icon-label, rule, and optical relationships.
| Token | Value | Intent |
|---|---|---|
space-1 |
4px | Micro separation and optical adjustment. |
space-2 |
8px | Compact inline and control-internal grouping. |
space-3 |
12px | Tight field, helper, and small cluster spacing. |
space-4 |
16px | Standard component inset and narrow page gutter. |
space-6 |
24px | Comfortable component inset and grid gutter. |
space-8 |
32px | Panel groups and tablet/wide page gutter. |
space-10 |
40px | Section interior break. |
space-12 |
48px | Major section rhythm and default control group break. |
space-16 |
64px | Page-level separation. |
space-20 |
80px | Landing emphasis and major breathing room. |
space-24 |
96px | Maximum ordinary section separation. |
Browser mechanics are not spacing tokens. auto, percentages, min-content, max-content, fit-content, clamp(), viewport and container units, minmax(), and intrinsic sizing remain explicit where they solve layout.
- Wide pages use a 16-column alignment frame with
space-8wide gutters andspace-4narrow gutters. It is an alignment aid, not a Carbon clone. - Reading content spans only the columns needed for a 65ch measure. Workspaces may consume the full frame.
- The HeroUI live reference supersedes the former fixed 4/8/12px-only geometry. Use
radius-base0.5rem,radius-medium0.375rem, andradius-field0.75rem; select among these roles by component anatomy rather than forcing every control, surface, and overlay into one rectilinear tier. Circular geometry remains reserved for avatars, plotted points, and inherently round controls. Pill geometry remains reserved for true tags, segmented controls whose reference anatomy requires it, or compact status labels. - Visual desktop controls use the reference's 36px height where density calls for it. Every control still exposes an effective target of at least 44x44px through its box or non-overlapping hit-area extension. Mobile and touch-primary controls may remain visually 44px or taller.
- The adapted HeroUI dashboard sidebar is a full-height 240px desktop profile-first rail. Its profile block is an ordinary elevated, bordered 208x44 identity surface at the 16px desktop inset; navigation chrome is 216x36 at the 12px row inset inside a 216x44 effective target, and only the current navigation chrome carries
interactive.selection; compact utility rows remain bottom-aligned. At 48rem through below 64rem, retain the approved 80px NeuronLab icon rail with keyboard/focus tooltips. Below 48rem, hide the rail and retain mobile bottom navigation plus More drawer. - Sidebar navigation rows use
space-2effective separation. Each row retains a separate, non-overlapping >=44px control box; the compact 36px visual chrome sits inside that accessible target. - Prefer named primitives:
stack,cluster,content-limiter,sidebar,switcher,reel,sticky-aside,scroll-body-shell,fixed-sidenav-shell, andlist-detail. - Page-frame changes use media queries. Reusable component adaptation uses intrinsic layout or container queries.
- Bounded shells use
grid-template-rows: auto minmax(0, 1fr) auto, a100dvbor100dvhbound, andmin-block-size: 0on the scroll child. - Fluid grid tracks use the overflow-safe form
minmax(min(<content floor>, 100%), 1fr). - Every fluid child that may contain equations, code, URLs, translated labels, or identifiers receives
min-inline-size: 0and an intentional wrap, truncate, or local-overflow policy. - Primary content never creates page-level horizontal scrolling. Use
overflow-wrap: anywherefor unbroken text; use local horizontal scrolling for code, equations, matrices, tables, and intrinsically two-dimensional diagrams. - Use logical properties so direction changes do not invalidate the layout.
| Surface model | Bound and fixed regions | Vertical scroll owner | Local overflow exceptions |
|---|---|---|---|
| Document: landing, login, register, diagnostic, profile, settings, roadmap, and long lesson reading | Browser document. A lesson outline may be sticky within document flow. | The document is the only vertical owner. | Math, code, and wide diagrams may scroll horizontally inside their own labeled surfaces. No second competing vertical scrollbar. |
| App shell: dashboard and authenticated application routes | Shell is bounded to 100dvb; masthead, adaptive sidebar, and mobile navigation remain shell chrome. |
The main content region is the named vertical owner and has min-block-size: 0. |
A long sidebar or anchored overlay may scroll for its named job. Dashboard summaries and timeline stay in one main flow. |
Split workspace: /problem/[id] |
Focus shell is bounded to 100dvb; workspace header and reachable run/progression controls stay fixed. The outer document does not scroll on desktop. |
Desktop statement pane and editor/results pane each own only their content. Mobile active tab panel is the sole workspace vertical owner. | Editor, test output, math, and diagrams may use local horizontal overflow. The divider is keyboard operable. |
The graph-paper lesson stage remains in lesson document flow. On wide screens its instruction strip may be sticky and the apparatus may remain visible, but neither creates an unbounded nested vertical scroll. The central mathematical canvas may pan or zoom only through an accessible interaction with non-gesture controls.
| Layout state | Behavior |
|---|---|
| Narrow, below the content-driven 48rem shell threshold | Single readable column; mobile bottom navigation; More drawer; roadmap becomes a labeled horizontal reel or compact stepper; instruction precedes canvas; apparatus becomes a bottom sheet or dedicated tab; progression action remains reachable; split problem panes become tabs. |
| Mid, 48rem through the content-driven 64rem workspace threshold | Compact sidebar; reduced chrome labels; flexible one- or two-region layouts; lesson apparatus may move below the canvas if side placement compromises the graph or prose. |
| Wide, 64rem and above | Full or compact adaptive sidebar; full mastery roadmap; graph-paper lesson composition may use instruction, canvas, and apparatus regions; problem route uses adjustable statement and editor/results panes. |
| Wide frame, 80rem and above | Use the full 16-column alignment frame while preserving 65ch reading measure and avoiding empty decorative expansion. |
Breakpoints are named by behavior and may be refined only when real content fails at a different width. The required proof viewports remain 390x844, 768x1024, and 1440x900, plus 375px content stress and 200% browser zoom at 1280px.
At 200% zoom, the effective layout follows the narrow or mid composition rather than shrinking type or forcing side-by-side panes. Navigation, dialogs, roadmap, lesson stages, editor controls, and recovery actions remain reachable. No primary content is lost, clipped, obscured by fixed chrome, or forced into two-dimensional page scrolling.
HeroUI v3 supplies ordinary controls. NeuronLab composes and tokens those controls; it does not reimplement their accessibility behavior. Section 5 names only the shared primitives required by the near-term scaffold, theme, shell, public-flow, and reliability tasks. Roadmaps, activity timelines, lesson canvases, math rendering, editors, execution results, reasoning, and Manim remain feature-specific until their implementation proves a shared pattern.
Every component defines the applicable states before product composition. Not applicable must be an explicit design decision, not a missing state.
| State | Required behavior |
|---|---|
| Default | Role, label, value, hierarchy, and affordance are clear without interaction. |
| Hover | Interactive elements only use interactive.hover; no hover-only meaning or required action. |
| Focus | interactive.focusRing is visible, theme-valid, not clipped, and paired with logical keyboard order. |
| Active / pressed | Immediate transform-only tactile feedback and interactive.active; semantic pressed state is announced when relevant. |
| Disabled | Unavailable behavior is explicit, non-color-only, and includes a reason where that reason helps progress. |
| Loading | Final geometry is reserved; the operation and blocked scope are announced; stop or cancel exists for long simulated work. |
| Empty | The absence is named and one relevant population or next action is provided. |
| Partial | Valid content remains visible; incomplete scope and recovery action are named. |
| Error | What happened and what to do next appear near the failed action; input and valid work are preserved. |
| Success | The confirmed outcome is named and the next focus target or next action is clear. |
| Selected | interactive.selection plus text, icon, marker, or semantic state identifies the current item. It never borrows primary.*. |
Applies means the primitive must implement the Section 5 state behavior. A scoped cell names the subpart that owns the state; the state is not applied to the primitive's other subparts. Every N/A cell is justified below the matrix.
| Primitive | Default | Hover | Focus | Active / pressed | Disabled | Loading | Empty | Partial | Error | Success | Selected |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Action | Applies | Applies | Applies | Applies | Applies | Applies | N/A | N/A | Applies | Applies | N/A |
| Field | Applies | Applies | Applies | Applies | Applies | Applies | Applies | N/A | Applies | Applies | N/A |
| Surface | Applies | Interactive only | Interactive only | Interactive only | Interactive only | Applies | Applies | Applies | Applies | Applies | Selectable only |
| Tabs | Applies | Applies | Applies | Applies | Applies | Tabpanel | Tabpanel | Tabpanel | Tabpanel | Tabpanel | Applies |
| Progress | Applies | N/A | N/A | N/A | N/A | Applies | N/A | Applies | Applies | Applies | N/A |
| Tooltip | Applies | Applies | Applies | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A |
| Overlay | Applies | N/A | Applies | N/A | N/A | Applies | Applies | Applies | Applies | Applies | N/A |
| Feedback boundary | Applies | N/A | Error focus only | N/A | N/A | Applies | Applies | Applies | Applies | Applies | N/A |
| Application shell | Applies | Navigation | Navigation | Navigation | N/A | Main content | Main content | Main content | Main content | Main content | Navigation |
| Focus shell | Applies | Controls | Controls | Controls | Execution controls | Workspace | Workspace | Workspace | Workspace | Workspace | Pane or tab |
Scoped applicability is deliberate:
- Static
Surfacevariants are N/A for hover, focus, active/pressed, disabled, and selected because they expose no interaction or selection affordance. Interactive or selectable variants own those states. Tabscontent-lifecycle states belong to the associatedtabpanel; the tab control itself retains its stable label and selected/disabled semantics.Feedback boundaryfocus applies only when focus must move to an error summary for comprehension or recovery; the non-interactive wrapper otherwise never enters the tab order.Application shellinteraction and selected states belong to navigation controls, while loading, empty, partial, error, and success belong to the named main-content owner.Focus shellinteraction and disabled states belong to its divider, tabs, and execution controls; content-lifecycle states belong to the workspace region.
Explicit N/A decisions:
Action: empty and partial are content-lifecycle states owned by a feature or feedback boundary, not by a command control; selected is owned by Tabs or another semantic selection control rather than a Button variant.Field: partial is represented as current input plus helper/error validation rather than a separate field state; selected belongs to the specific selection control, not the text/search Field primitive.Progress: hover, focus, active/pressed, and disabled are N/A because this primitive is a non-interactive status indicator; empty is represented by omitting Progress and naming the absence in a feedback boundary; selected has no meaning for a single operation's progress.Tooltip: active/pressed is owned by its trigger, and Tooltip has no independent disabled, loading, empty, partial, error, success, or selected lifecycle. Essential state or recovery content must not be placed in Tooltip.Overlay: hover and active/pressed belong to child controls, disabled belongs to the trigger, and selected belongs to a child option or tab; the overlay container does not duplicate those semantics.Feedback boundary: hover and active/pressed are N/A because the boundary is not interactive; disabled belongs to its child action; selected belongs to the content control that owns selection.Application shell: disabled is N/A because route availability is expressed by authored destinations and lock explanations, not by disabling the shell.
| Primitive | Structure and variants | Tokens and spacing | Applicable states | Accessibility, layout, and motion |
|---|---|---|---|---|
| Action | HeroUI Button; primary, secondary/outline, quiet/ghost, destructive, and icon-only; standard and compact desktop sizes. |
primary.*, interactive.*, appropriate status.error.*; space-2 to space-4; radius-medium or the HeroUI anatomy derived from radius-base. |
Per matrix: default, hover, focus, active/pressed, disabled, loading, error, success. | Native button semantics; icon-only action has an accessible name; labels do not wrap; 36px visual desktop control with at least 44px effective target; press uses source primary.active plus brief tactile feedback and no movement for repeated keyboard activation. |
| Field | HeroUI Input or search control; visible label above, helper or error below, optional leading/trailing action. |
surface.elevated, surface.foreground, surface.subtle, interactive.*, status.error.*; space-2 and space-3; radius-field; no ordinary shadow. |
Per matrix: default, hover, focus, active/pressed, disabled, loading, empty, error, success. | Label and description are programmatically associated; placeholder never replaces label; error uses text and live association; no layout-shifting border; no motion beyond brief opacity for status text. |
| Surface | HeroUI Card only where grouping or interaction requires a bounded region; static panel, interactive tile, selected tile. |
surface.background, surface.muted, or surface.elevated; interactive.border only when needed; space-4, space-6, or space-8; radius-base; no ordinary shadow. |
Per matrix: all states, with interaction and selection states limited to matching variants. | Static surfaces have no hover. Interactive surfaces use a semantic button/link wrapper. Prefer zoning or spacing over nested cards; tonal shift, border, and spacing own ordinary separation. |
| Tabs | HeroUI Tabs; underline or clean segmented treatment; route-local and workspace variants. |
interactive.*, surface.*; space-2 and space-4; radius-medium for segmented form. |
Per matrix: all states; the tabpanel owns content-lifecycle states. | Correct tablist/tab/tabpanel semantics; arrow-key navigation; DOM order follows reading order; the built-in selected indicator may transition its state-bearing geometry and becomes instant under reduced motion. Mobile tab lists may use a keyboard-accessible reel. |
| Progress | HeroUI Progress; determinate diagnostic progress, indeterminate operation progress, and text-backed completion state. |
surface.*, primary.* for active task progress, status.* only for outcome; space-2. |
Per matrix: default, loading, partial, error, success. | Value and total are available as text; no color-only meaning; progress updates are announced at useful intervals; the built-in fill may transition its state-bearing geometry and becomes instant under reduced motion. |
| Tooltip | HeroUI Tooltip for concise supplementary help only. |
surface.elevated, surface.foreground, interactive.border; space-2; radius-base; shadow-overlay. |
Per matrix: default (closed), hover-open, focus-open. | Same information is reachable by keyboard and touch; not used for essential instructions; origin-aware appearance uses opacity and small transform, with immediate reduced-motion rendering. |
| Overlay | HeroUI dialog, menu, drawer, or bottom sheet; dialog for focused decisions, anchored menu for compact choices, drawer/sheet for narrow navigation and lesson apparatus. | surface.elevated, surface.foreground, interactive.*; space-4 to space-8; the appropriate radius-base family role; shadow-overlay. |
Per matrix: default (closed), focus, loading, empty, partial, error, success; open/close are interaction phases. | Labelled title; focus trap and return; Escape closes unless the operation requires explicit choice; background is inert; narrow apparatus has a non-drag control; HeroUI's accessible motion is retained with reduced-motion handling. |
| Feedback boundary | HeroUI skeleton, alert, progress, and action composed as loading, empty, partial, error, success, or persistence warning. | surface.*, status.*, interactive.*; space-3 to space-6; radius-surface. |
Per matrix: default, error-summary focus, loading, empty, partial, error, success. | Skeleton preserves final geometry; live regions avoid repeated announcements; retry targets only the failed operation; partial content stays mounted; focus moves only when needed to understand or recover. |
| Application shell | Masthead, adaptive sidebar, main region, mobile bottom navigation, More drawer, and non-dismissible Prototype mode label. Desktop sidebar uses HeroUI dashboard provenance adapted to NeuronLab: profile block first, Overview/Learning grouped links, bottom Profile/Settings/Logout when authenticated, semantic inset separator, flat surface, no ordinary shadow. Shared inline SVG icons use currentColor, one 1.75 stroke weight, aria-hidden, and focusable=false; letter marks and emoji are prohibited. |
surface.*, interactive.*; 240px/80px responsive rail plus 16px/12px/36px reference geometry and Section 4 spacing tokens. |
Per matrix: default; navigation hover, focus, active/pressed, selected; main-content loading, empty, partial, error, success. | Uses the app-shell scroll contract; current-page state is singular within each visible navigation surface; profile identity remains accessible in rail and compact tooltip forms; mobile More closes before authenticated logout; no viewport branching in React. |
| Focus shell | Workspace header, statement region, adjustable divider, editor/results region, mobile tabs, and reachable run/progression controls. | surface.*, interactive.*, syntax.*, and local status.*; frame and spacing tokens from Section 4. |
Per matrix: every state, scoped to controls, execution, workspace content, or selected pane/tab as named. | Uses the split-workspace scroll contract; divider is keyboard operable; Monaco escape instructions are visible and documented; mobile uses tabs rather than compressed panes. |
Before product screens are composed, the actual shared Action, Field, Surface, Tabs, Progress, Tooltip, Overlay, and feedback patterns must appear in the primitive showcase with every applicable state. Verify at 390x844, 768x1024, and 1440x900 in representative light and dark variants, with keyboard, reduced motion, long labels, unbroken strings, empty data, and 200% zoom. A missing state blocks downstream screen composition.
Motion communicates a state change, spatial relationship, or next focus. It never exists to make the laboratory theme feel busy. Native CSS transitions or WAAPI cover this motion level; no motion dependency is added unless a later shared-layout or spring requirement is separately approved.
| Token | Value | Use |
|---|---|---|
motion.none |
0ms | Reduced-motion and repeated keyboard actions. |
motion.feedback |
150ms | Press, hover, focus-supporting opacity, and compact control feedback. |
motion.state |
200ms | Tab indicator, selected state, local status swap, and short disclosure. |
motion.panel |
220ms | Drawer, sheet, dialog, or panel relationship. |
motion.easeOut |
cubic-bezier(0.23, 1, 0.32, 1) |
Entering and direct-response transitions. |
motion.easeInOut |
cubic-bezier(0.77, 0, 0.175, 1) |
On-screen state movement that remains visible throughout. |
| Interaction | What motion communicates | Standard path | Reduced-motion path |
|---|---|---|---|
| Action press | The control received input. | 150ms transform to scale(0.96) and back. |
Immediate state change with no spatial transform. |
| Diagnostic or lesson stage change | The learner advanced and the current step changed. | Current marker and panel use transform/opacity within 200ms. | Current marker and panel update immediately or with a brief opacity change. |
| Tab or pane switch | The selected control and content panel are related. | Indicator uses transform; panel uses opacity. | Instant indicator and panel update. |
| Drawer, sheet, or dialog | The floating surface came from a trigger or edge. | Transform plus opacity within 220ms; focus moves after open. | Immediate open/close with focus management intact. |
| Graph manipulation | Point, guides, tangent, coordinates, and derivative are one live model. | Direct, interruptible transform or canvas update tied to pointer/keyboard input. | The same value changes without smoothing; non-drag controls remain available. |
| Simulated operation state | A run, reasoning stream, or Manim job changed state. | Opacity swap for status content; progress transform when meaningful. | Immediate textual and live-region update. |
- Prefer compositor-friendly
transform,opacity, and narrowly justifiedfilterfor custom NeuronLab motion. This supersedes the former blanket transform/opacity-only restriction: HeroUI's built-in accessible component motion may animate progress or selection-indicator geometry when that geometry communicates the component's value or selected state. - Do not animate page or shell layout, grid tracks, graph-paper lines, decorative dimensions, or arbitrary geometry. Width/height changes remain prohibited except for a HeroUI progress or selection indicator whose geometry is the state itself; keep those transitions short, interruptible, and measured for layout cost before accepting them.
- Do not animate initial page load, scroll position, keyboard-triggered repeated actions, decorative laboratory motifs, or anything that delays task completion.
- No perpetual animation, autoplay, parallax, scroll hijacking, marquee, or decorative pulse.
- Hover states are gated to devices that support hover and fine pointers. Required behavior is never hover-only.
- Gestures have keyboard and button alternatives. Dragging the plotted point has step controls; dragging a divider has keyboard increments; opening a bottom sheet never requires a swipe.
- Under
prefers-reduced-motion: reduce, spatial movement is removed. State remains perceivable through immediate rendering, text, and at most brief opacity.
HeroUI's medium-radius anatomy remains authoritative, but the user explicitly selects flat-modern depth rather than macOS-like dimensional material. OpenChamber tonal surfaces, thin borders, precise dividers, and spacing own ordinary hierarchy. Cards, fields, buttons, tabs, headers, sidebars, avatars, badges, selected navigation, and lifecycle surfaces have no shadow. Only genuine overlap uses shadow-overlay; its color is derived with color-mix() from resolved semantic colors, so no reference raw color, neutral ramp, black literal, glow, or glass palette enters the application.
| Level | Semantic treatment | Use |
|---|---|---|
| Base | surface.background |
Document and shell canvas. |
| Muted zone | surface.muted |
Secondary band, apparatus zone, or quiet grouped content. Application shell header, sidebar, and mobile navigation remain on the base canvas. |
| Working surface | surface.elevated plus interactive.border where needed |
Fields, bounded work panels, equation cards, and content that must separate from its parent. |
| Subtle separation | surface.subtle or interactive.border |
Hairline, local graph grid, and structural divider only where spacing or tonal change is insufficient. |
| Selection | interactive.selection plus interactive.selectionForeground |
Current navigation, stage, tab, roadmap item, and theme choice. |
- Ordinary controls, bounded surfaces, shell chrome, selected states, and lifecycle regions never use
shadow-surfaceorshadow-field; those former roles are superseded. - Menus, tooltips, dialogs, drawers, sheets, and similar surfaces that genuinely overlap content use the stronger overlay shadow and a semantic scrim.
- Overlay and scrim colors derive only from
surface.foreground,surface.background, or their mapped HeroUI roles throughcolor-mix(); they never introduce literal colors or a separate palette. - Repeated nested cards and decorative elevation remain prohibited. Use tonal shift, thin border, and spacing before adding another bounded surface.
- The technical grid is localized to the mathematical canvas and uses Section 2 semantic relationships.
- Grid hierarchy comes from line weight and semantic role, not extra hues.
- A restrained static paper grain may be applied only inside the canvas as non-interactive background material. It is derived from
surface.foreground, remains below text and graph marks, does not reduce contrast, and is not elevation. - Formula cards may use
surface.elevated,interactive.border, and the medium-radius HeroUI geometry because they sit over the graph plane. They remain quiet and subordinate to the mathematics. - Dark themes preserve the same hierarchy through their resolved surfaces. The canvas does not force a light paper patch inside a dark application.
NeuronLab targets WCAG 2.2 AA across all core routes and all 42 theme variants. Accessibility outranks reference fidelity and taste.
| Area | Contract |
|---|---|
| Contrast | Body text at least 4.5:1; large text and essential UI boundaries at least 3:1; focus indicator at least 3:1 against adjacent colors. All required pairs are validated per variant. |
| Keyboard | Every action, tab, roadmap item, disclosure, dialog, drawer, graph control, split divider, editor escape path, run control, and retry is reachable and operable without a pointer. No keyboard trap. |
| Focus | Focus is visible, theme-correct, not clipped, and restored after overlays. Focus moves only when needed for comprehension or recovery. |
| Screen reader | Landmarks, one H1, logical heading levels, visible labels, current/selected/expanded/disabled states, useful live regions, and associated errors are required. DOM order remains meaningful when the visual grid reflows. |
| Math and diagrams | Equations have semantic or textual fallbacks. Complex graphs and Mermaid diagrams provide a concise summary plus detailed text. Render failure preserves the text explanation. |
| Color independence | Mastery, lock, selection, status, graph series, and validation use labels plus icons, patterns, line styles, or text. |
| Touch and gestures | Minimum effective target is 44x44px. Visual desktop controls may be 36px per the HeroUI reference when their effective target is extended without overlap; touch-primary controls remain 44px or taller. Gestures always have control and keyboard alternatives. |
| Motion | Section 6 and prefers-reduced-motion are mandatory. No flashing, autoplay, decorative loops, or task-delaying animation. |
| Resize and reflow | At 200% zoom and 320-375px widths, primary content reflows without page-level horizontal scroll, clipping, overlap, or fixed-chrome obstruction. Local two-dimensional surfaces remain labeled and keyboard scrollable. |
| Text spacing and locale | Text tolerates WCAG spacing overrides, long translated labels, CJK content, unbroken strings, and readable line length. Controls do not rely on fixed copy width. |
| Error and recovery | Errors state what happened and what to do. Input and valid work are preserved. Destructive reset requires explicit confirmation and affects only the current mock user. |
| Cognitive access | One primary action per context; stable stage labels; visible progress and prerequisites; progressive disclosure; no time pressure; plain language; interruption recovery; and no requirement to remember information from a previous screen. |
| Persona | Context and task | Pass criteria |
|---|---|---|
| Ari | Novice learner with math anxiety and limited working memory; fails a conceptual check, enters remediation, and returns after interruption. | Current position, prerequisite, failure reason, preserved work, and one next action remain visible. Language is neutral, short, and free of time pressure or shame. |
| Maya | Blind screen-reader user working by keyboard; completes diagnostic, reads a derivation, switches panes, runs code, and opens hints. | Logical landmarks and headings, labeled controls, useful announcements, math and diagram alternatives, deterministic focus, full keyboard operation, and a documented Monaco escape path. |
| Dimas | Low-vision learner with color-vision deficiency at 200% zoom across light and dark variants. | Per-role contrast passes, focus is visible, states use text plus another cue, equations overflow locally, and no content clips, overlaps, or forces page-level horizontal scroll. |
| Sari | Learner with ADHD in a distracting environment; moves among lesson stages, activity history, lock explanations, and partial streams. | Navigation and stage labels stay stable, hints disclose progressively, partial output remains, competing CTAs are absent, and recovery sits beside the failed action. |
| Raka | Learner with a temporary wrist injury using one hand on a phone; navigates, changes tabs, opens More, and retries execution. | At least 44x44px effective targets, reachable bottom navigation, no hover-only behavior, trapped-and-restored drawer focus, and tabs instead of squeezed split panes. |
| Nadia | Advanced learner interrupted by execution or persistence warnings; returns to partial work after retry or reload. | Valid work and completed output remain, save status is honest, stop/retry does not destructively reset, and the roadmap return path is explicit. |
Every relevant route is exercised with empty activity, no avatar, long translated labels, 65ch prose, unbroken URLs, wide equations, dense code output, partial streams, inline errors, persistence failure, and canceled operations. Core-flow testing covers diagnostic failure, mastery lock, remediation, execution failure, stream retry, and current-user reset confirmation.
No accessibility failure is accepted as debt. Critical or major persona, WCAG, keyboard, screen-reader, reflow, or contrast failures block progress. The following bounded V1 design debts are accepted by the approved mock-prototype scope and retain explicit exits.
| ID | Item and location | Why accepted now | Owner / exit |
|---|---|---|---|
DD-001 |
Task 0 research is reference-led and persona-led rather than validated with direct learner interviews. | The approved phase is a deterministic prototype used to prove the model, not a production launch or research claim. | Product owner: run moderated usability and accessibility research with representative learners before approving backend integration or production positioning. |
DD-002 |
Semantic behavior for all 42 OpenChamber variants is contractual but not yet rendered or contrast-tested. | Task 0 defines the mapping; implementation and matrix evidence belong to Tasks 2-4 and 14. | Theme workers: resolver tests, source-ID focus corrections, hydration proof, and the complete visual/contrast matrix must pass before theme publication. |
DD-003 |
graph-paper-studio.png is desktop-led; narrow and 200% zoom behavior is specified but not yet rendered. |
The concept is a reference-fidelity input, not implementation evidence. | Shell, lesson, and problem workers: verify the documented reflow in Tasks 7, 10, and 11 through browser and visual QA evidence. |
DD-004 |
Mathematical, execution, reasoning, and Manim content remains deterministic or simulated in V1. | This is an explicit approved non-goal and keeps the frontend independent of a backend or external service. | Product owner: require a separately approved integration design before any real service is connected or correctness claim is made. |
Later implementation is not design-complete until the primitive showcase passes, representative light and dark variants retain hierarchy, all applicable states work, the core route matrix passes keyboard and axe checks, 200% zoom and reduced motion pass, and /visual-qa inspects actual rendered surfaces at the required viewports. Independent review may reject this contract or any implementation that leaves an unresolved blocking accessibility issue.