Guidelines for modifying the 21-step guided tutorial walkthrough.
The tutorial is a multi-step guided walkthrough defined across several tightly coupled files. Changes require careful coordination.
| File | What it contains |
|---|---|
frontend/src/hooks/useTutorial.ts | TUTORIAL_STEPS[] array (step definitions) + useIsStepSatisfied() (gating conditions) |
frontend/src/components/TutorialOverlay.tsx | Step sets, step-specific useEffect hooks, highlight logic |
frontend/src/components/Dashboard.tsx | Hardcoded step range for tutorial-step-settings CSS class |
frontend/src/styles/app.css | .tutorial-highlight styles and variants |
Step indices are hardcoded in all four files. When inserting or removing a step, update every reference:
useTutorial.ts — add/remove entry in TUTORIAL_STEPS[], update all case numbers in useIsStepSatisfied()TutorialOverlay.tsx — update these step sets to match new indices:
STEPS_REQUIRING_PANEL_OPEN — steps that need the options panel openSTEPS_IN_NAVBAR — steps targeting navbar elementsSETTINGS_STEPS — steps that show the settings modalTutorialOverlay.tsx — update step !== N checks in every step-specific useEffect hook (tab cycling, split mode setup, reactant selection, etc.)Dashboard.tsx — update the tutorialStep >= N && tutorialStep <= M range for settings stepsChecklist after any step change:
TUTORIAL_STEPS[] array updateduseIsStepSatisfied() cases renumberedSTEPS_REQUIRING_PANEL_OPEN, STEPS_IN_NAVBAR, SETTINGS_STEPS) updateduseEffect hooks reference correct step numbersDashboard.tsx settings step range updatednpx tsc --noEmit and npx vitest runHighlights are applied by adding the tutorial-highlight class to the target element via its targetId.
Always use background fill, not just outline. Outline alone is too subtle — users won't notice it. Use background: var(--color-primary-light) for light-background elements.
Navbar elements need inverted highlights. The navbar has a dark background, so --color-primary-light makes text unreadable. Use background: rgba(255, 255, 255, 0.2) instead. The .navbar .tutorial-highlight rule handles this.
Don't add extra padding to highlighted elements. It shifts layout and the user will reject it. Use outline-offset and matching box-shadow spread to extend the highlight area without affecting layout.
Match box-shadow spread to outline-offset. If outline-offset: 3px, use box-shadow: 0 0 0 3px. Mismatched values look wrong.
Check for inline styles before adding CSS. Some elements (e.g., .filter-panel) have inline styles in their component that override CSS. If your CSS change has no effect, check the component's JSX for inline style={}.
| Element | Background | Outline |
|---|---|---|
Default (.tutorial-highlight) | none | 2px solid var(--color-primary) |
Buttons (button.tutorial-highlight) | var(--color-primary-light) | 2px solid var(--color-primary) |
Dropdowns (.control-col.tutorial-highlight) | var(--color-primary-light) | inherited + outline-offset: 3px |
Sliders/checkboxes (.slider-group, label) | var(--color-primary-light) | inherited + outline-offset: 3px |
Download buttons (#download-buttons) | var(--color-primary-light) | inherited |
Navbar elements (.navbar .tutorial-highlight) | rgba(255, 255, 255, 0.2) | white outline |
Plotly.relayout() to reset zoom: Plotly.relayout(div, { 'xaxis.autorange': true, 'yaxis.autorange': true })addEventListener('plotly_relayout', ...) does NOT work. Use the onInitialized callback from react-plotly.js to get the graph div, then register via graphDiv.on('plotly_relayout', handler).useZoomReset() hook in DistributionView.tsx encapsulates this pattern — reuse it in any new plot component.